#pragma once

#include <string>
#include "Utils.hpp"

namespace nio {

	class SocketError {
		std::string reason;
		int code = 0;
	public:
		SocketError(std::string reason, int code) {
			this->reason = reason;
			this->code = code;
		}

		std::string toString() {
			auto strErr = strerr(code);
			if (code == 0)return reason;
			return Utils::format("%s(%d:%s)", reason.c_str(), code, strErr.c_str());
		}
	private:
#ifdef _WIN32
		std::string strerr(int code) {
			DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER
				| FORMAT_MESSAGE_FROM_SYSTEM
				| FORMAT_MESSAGE_IGNORE_INSERTS;

			LPSTR errMsg = nullptr;

			DWORD dwResult = FormatMessageA(dwFlags, NULL, code
				, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&errMsg, 0, NULL);

			if (dwResult == 0 || errMsg == nullptr) {
				return "Unknown error";
			}

			std::string str(errMsg);
			LocalFree(errMsg);
			return str;
		}
#else
		std::string strerr(int code) {
			char* errStr = strerror(code);
			if (errStr == nullptr) {
				return "Unknown error";
			}
			return std::string(errStr);
		}
#endif // _WIN32
	};

}